package cn.itsource.stream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;

/**
 *	IO流：
 *		分类：
 *					输入流			 		输出流
			字节流	InputStream（抽象类）     	OutputStream（抽象类）
			字符流	Reader （抽象类）       	 	Writer（抽象类）
			
	字节流：
 *		使用场景：
 *		1.字节流处理除了文本、文字相关所有的流问题，如，png/jpg/avi/map4/mp3/exe
 *		2.字符流只处理文本、文字相关
 *
 *		1.输入流	abstract class InputStream:这个抽象类是表示输入字节流的所有类的超类。
 *								|
 *							FileInputStream 子类
 *								1. 构造方法
 *										FileInputStream(String name) 	name：表示(绝对路径、相对路径)文件名
 *										FileInputStream(File file) 
 *
 *								2. 普通方法：
									//1. int read(byte[] b) 从输入流读取一些字节数，并将它们存储到缓冲区 b 。  最常用
 *									//2. int read() 从输入流读取数据的下一个字节。  
									//3. int read(byte[] b, int off, int len) 	从输入流读取最多 len字节的数据到一个字节数组。	
									
									
 *		2.输出流	abstract class OutputStream:这个抽象类是表示输出字节流的所有类的超类。
 *								|
 *							FileOutputStream 子类
 *								1. 构造方法
										FileOutputStream(String name) 
										FileOutputStream(String name, boolean append) 
										append：表示是否在该文件末尾追加数据，如果为true，表示追加，false，表示从头开始覆盖
 *										FileOutputStream(File file) 
										FileOutputStream(File file, boolean append) 
 *								
 *								2. 普通方法：
 *									//1. void write(byte[] b)将 b.length个字节从指定的字节数组写入此文件输出流。  
									//2. void write(byte[] b, int off, int len) 	将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。  最常用
									//3. void write(int b) 将指定的字节写入此文件输出流。  
		3. 注意事项：
				1. 必须要关闭IO流，节约资源开销
				2. 关闭IO流原则，先开后关
 */
public class InputStreamTest {

	public static void main(String[] args) {
		/*
		 * FileInputStream 子类
			1. 构造方法
					FileInputStream(String name) 
					FileInputStream(File file) 
					
				必须要关闭IO流，节约资源开销
		 */
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("inputsteam.txt");
			
			//调用方法读取数据
			//1. int read() 从输入流读取一个字节的数据，如果没有数据了，返回值是-1。  
			/*int read = fis.read();//每次调用该方法，都会读取一个，然后指针后移一位
			System.out.println(read);
			System.out.println((char)read);
			
			read = fis.read();//每次调用该方法，都会读取一个，然后指针后移一位
			System.out.println(read);
			System.out.println((char)read);
			
			read = fis.read();//每次调用该方法，都会读取一个，然后指针后移一位
			System.out.println(read);
			System.out.println((char)read);
			用循环优化
			*/
			//声明一个变量，用来专门保存读取的每一个字节
//			int read = -1;
//			while ((read = fis.read()) != -1) {//为了将读取的字节保存所以用read = fis.read()这种方式
//				System.out.println((char)read);//用字节流读取中文会乱码，所以，读取中文相关的文件不会用字节流
//			}
			
			/*//声明一个字节数组，装每次读取的数据
			byte[] b = new byte[10];
			//2. int read(byte[] b) 从输入流读取一些字节数，并将它们存储到缓冲区 b 。  
			int read = -1;//表示每次读取的真正的字节个数
			read = fis.read(b);//将读取的数据保存到byte数组b中，返回值read是表示读取的字节数
			System.out.println("读取了： " + read + "字节");
			System.out.println("读取的数据是：" + Arrays.toString(b));
			
			read = fis.read(b);//将读取的数据保存到byte数组b中，返回值read是表示读取的字节数
			System.out.println("读取了： " + read + "字节");
			System.out.println("读取的数据是：" + Arrays.toString(b));*/
			
			
			//3. int read(byte[] b, int off, int len) 	从输入流读取最多 len字节的数据到一个字节数组。	
//			byte[] b = new byte[10];
//			int read = -1;//表示每次读取的真正的字节个数
//			int read2 = fis.read(b,0,b.length);
//			System.out.println(read2);
//			read2 = fis.read(b,0,b.length);
//			System.out.println(read2);
			
			//这是最常用的方式			只需要掌握这一个方法即可
			byte[] b = new byte[10];
			int read = -1;//表示每次读取的真正的字节个数
			//将byte数组转换为字符串的方法	=>：解码		这是最常用的方式
			while((read = fis.read(b)) != -1){//read是-1表示读完了，记录每次读取的字节个数，读取的数据是装在byte数组中
				System.out.println(new String(b,0,read));//将读取的byte数组转换为String
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//先判断是否为null
			if (fis != null) {
				try {
					//1. 必须要关闭IO流，节约资源开销		2. 关闭IO流原则，先开后关
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}

}
